﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Bule.Components.FilteredSelectionList;
using Bule.Components.InputBox;
using Bule.Malbilden.Data;
using Bule.Malbilden.Domain;
using Bule.Malbilden.Util;

namespace Bule.Malbilden.Forms
{
    public partial class FoodProductView : Form
    {
        private IPersistentContext context;
        private FoodProduct currentProduct;
        private IListViewItemListCreator listCreator;

        private bool hasMadeChange;

        public FoodProductView(IPersistentContext context, IListViewItemListCreator listCreator)
        {
            InitializeComponent();

            this.context = context;
            this.listCreator = listCreator;
        }

        private void ChangeFoodProduct()
        {
            hasMadeChange = false;

            List<ListViewItem> itemList = listCreator.CreateFoodProductList();
            FilteredSelectionListDialog selector = new FilteredSelectionListDialog("Välj livsmedel att redigera", itemList);

            if (selector.ShowDialog() == DialogResult.OK && selector.SelectedItem != null)
            {
                currentProduct = (FoodProduct)selector.SelectedItem.Tag;

                UpdateTextboxValues(currentProduct.NutritionPerHundredGrams);
                UpdateControlEnabledState();
            }
        }

        private void UpdateTextboxValues(NutritionData nutrition)
        {
            nameTextbox.Text = currentProduct.Name;
            portionNameTextbox.Text = currentProduct.PortionName;
            portionSizeTextbox.Text = Convert.ToString(currentProduct.PortionSize);
            kcalTextbox.Text = Convert.ToString(nutrition.Kcal);
            proteinTextbox.Text = Convert.ToString(nutrition.Protein);
            carbsTextbox.Text = Convert.ToString(nutrition.Carbohydrates);
            unsaturatedFatTextbox.Text = Convert.ToString(nutrition.UnsaturatedFat);
            saturatedFatTextbox.Text = Convert.ToString(nutrition.SaturatedFat);
            fiberTextbox.Text = Convert.ToString(nutrition.Fiber);
            vitaminATextbox.Text = Convert.ToString(nutrition.VitaminA);
            vitaminB1Textbox.Text = Convert.ToString(nutrition.VitaminB1);
            vitaminB2Textbox.Text = Convert.ToString(nutrition.VitaminB2);
            vitaminB3Textbox.Text = Convert.ToString(nutrition.VitaminB3);
            vitaminB6Textbox.Text = Convert.ToString(nutrition.VitaminB6);
            vitaminB12Textbox.Text = Convert.ToString(nutrition.VitaminB12);
            vitaminCTextbox.Text = Convert.ToString(nutrition.VitaminC);
            vitaminDTextbox.Text = Convert.ToString(nutrition.VitaminD);
            vitaminETextbox.Text = Convert.ToString(nutrition.VitaminE);
            folicAcidTextbox.Text = Convert.ToString(nutrition.FolicAcid);
            calciumTextbox.Text = Convert.ToString(nutrition.Calcium);
            ironTextbox.Text = Convert.ToString(nutrition.Iron);
            sodiumTextbox.Text = Convert.ToString(nutrition.Sodium);
            potassiumTextbox.Text = Convert.ToString(nutrition.Potassium);
            phosphorusTextbox.Text = Convert.ToString(nutrition.Phosphorus);
            magnesiumTextbox.Text = Convert.ToString(nutrition.Magnesium);
            zincTextbox.Text = Convert.ToString(nutrition.Zinc);
            seleniumTextbox.Text = Convert.ToString(nutrition.Selenium);
        }

        private void newButton_Click(object sender, EventArgs e)
        {
            bool wasDialogCompleted = PromptUserToSaveChanges();

            if (wasDialogCompleted)
                CreateNewFoodProduct();
        }

        private void CreateNewFoodProduct()
        {
            InputBox inputbox = new InputBox("Ange namn", "Ange namnet på det livsmedel du vill lägga till:", false);

            if (inputbox.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(inputbox.Input))
            {
                ClearTextboxes();
                nameTextbox.Text = inputbox.Input;
                currentProduct = new FoodProduct();
                UpdateControlEnabledState();
            }
        }

        private void ClearTextboxes()
        {
            nameTextbox.Text = "";
            portionNameTextbox.Text = "portion";
            portionSizeTextbox.Text = "100";
            kcalTextbox.Text = "0";
            proteinTextbox.Text = "0";
            carbsTextbox.Text = "0";
            unsaturatedFatTextbox.Text = "0";
            saturatedFatTextbox.Text = "0";
            fiberTextbox.Text = "0";
            vitaminATextbox.Text = "0";
            vitaminB1Textbox.Text = "0";
            vitaminB2Textbox.Text = "0";
            vitaminB3Textbox.Text = "0";
            vitaminB6Textbox.Text = "0";
            vitaminB12Textbox.Text = "0";
            vitaminCTextbox.Text = "0";
            vitaminDTextbox.Text = "0";
            vitaminETextbox.Text = "0";
            folicAcidTextbox.Text = "0";
            calciumTextbox.Text = "0";
            ironTextbox.Text = "0";
            sodiumTextbox.Text = "0";
            potassiumTextbox.Text = "0";
            phosphorusTextbox.Text = "0";
            magnesiumTextbox.Text = "0";
            zincTextbox.Text = "0";
            seleniumTextbox.Text = "0";
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void saveButton_Click(object sender, EventArgs e)
        {
            SaveFoodProduct();
        }

        private void SaveFoodProduct()
        {
            hasMadeChange = false;
            UpdateFoodProductFromForm();
            context.Save(currentProduct.NutritionPerHundredGrams);
            context.Save(currentProduct);
        }

        private void removeButton_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("Livsmedel kan endast tas bort om de ej finns i någon kostdagbok.\n" +
                                                    "Vill du verkligen ta bort livsmedlet ur databasen?",
                                                    "Bekräfta borttagning",
                                                    MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (result == DialogResult.Yes)
            {
                context.Remove(currentProduct.NutritionPerHundredGrams);
                context.Remove(currentProduct);

                currentProduct = null;

                ClearTextboxes();
                UpdateControlEnabledState();
            }
        }

        private void renameButton_Click(object sender, EventArgs e)
        {
            InputBox inputBox = new InputBox("Ange namn", "Ange nytt namn för livsmedlet", false);
            DialogResult result = inputBox.ShowDialog();

            nameTextbox.Text = inputBox.Input;

            hasMadeChange = true;
        }

        private void changeButton_Click(object sender, EventArgs e)
        {
            bool wasDialogCompleted = PromptUserToSaveChanges();

            if (wasDialogCompleted)
                ChangeFoodProduct();
        }

        private void UpdateFoodProductFromForm()
        {
            currentProduct.Name = nameTextbox.Text;
            currentProduct.PortionName = portionNameTextbox.Text;
            currentProduct.PortionSize = Convert.ToDouble(portionSizeTextbox.Text);

            currentProduct.NutritionPerHundredGrams.Kcal = Convert.ToDouble(kcalTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Protein = Convert.ToDouble(proteinTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Carbohydrates = Convert.ToDouble(carbsTextbox.Text);
            currentProduct.NutritionPerHundredGrams.UnsaturatedFat = Convert.ToDouble(unsaturatedFatTextbox.Text);
            currentProduct.NutritionPerHundredGrams.SaturatedFat = Convert.ToDouble(saturatedFatTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Fiber = Convert.ToDouble(fiberTextbox.Text);
            currentProduct.NutritionPerHundredGrams.VitaminA = Convert.ToDouble(vitaminATextbox.Text);
            currentProduct.NutritionPerHundredGrams.VitaminB1 = Convert.ToDouble(vitaminB1Textbox.Text);
            currentProduct.NutritionPerHundredGrams.VitaminB2 = Convert.ToDouble(vitaminB2Textbox.Text);
            currentProduct.NutritionPerHundredGrams.VitaminB3 = Convert.ToDouble(vitaminB3Textbox.Text);
            currentProduct.NutritionPerHundredGrams.VitaminB6 = Convert.ToDouble(vitaminB6Textbox.Text);
            currentProduct.NutritionPerHundredGrams.VitaminB12 = Convert.ToDouble(vitaminB12Textbox.Text);
            currentProduct.NutritionPerHundredGrams.VitaminC = Convert.ToDouble(vitaminCTextbox.Text);
            currentProduct.NutritionPerHundredGrams.VitaminD = Convert.ToDouble(vitaminDTextbox.Text);
            currentProduct.NutritionPerHundredGrams.VitaminE = Convert.ToDouble(vitaminETextbox.Text);
            currentProduct.NutritionPerHundredGrams.FolicAcid = Convert.ToDouble(folicAcidTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Calcium = Convert.ToDouble(calciumTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Iron = Convert.ToDouble(ironTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Sodium = Convert.ToDouble(sodiumTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Potassium = Convert.ToDouble(potassiumTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Phosphorus = Convert.ToDouble(phosphorusTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Magnesium = Convert.ToDouble(magnesiumTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Zinc = Convert.ToDouble(zincTextbox.Text);
            currentProduct.NutritionPerHundredGrams.Selenium = Convert.ToDouble(seleniumTextbox.Text);
        }

        private void numericTextbox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (InputFilter.GivesValidNumeric(e.KeyChar, ((TextBox)sender).Text))
                hasMadeChange = !char.IsControl(e.KeyChar);
            else
                e.Handled = true;
        }

        private void UpdateControlEnabledState()
        {
            bool isProductSelected = (currentProduct != null);

            SetTextboxesEnabledState(isProductSelected);

            renameButton.Enabled = isProductSelected;
            removeButton.Enabled = isProductSelected;
            saveButton.Enabled = isProductSelected;
        }

        private void SetTextboxesEnabledState(bool isEnabled)
        {
            portionNameTextbox.Enabled = isEnabled;
            portionSizeTextbox.Enabled = isEnabled;
            kcalTextbox.Enabled = isEnabled;
            proteinTextbox.Enabled = isEnabled;
            carbsTextbox.Enabled = isEnabled;
            unsaturatedFatTextbox.Enabled = isEnabled;
            saturatedFatTextbox.Enabled = isEnabled;
            fiberTextbox.Enabled = isEnabled;
            vitaminATextbox.Enabled = isEnabled;
            vitaminB1Textbox.Enabled = isEnabled;
            vitaminB2Textbox.Enabled = isEnabled;
            vitaminB3Textbox.Enabled = isEnabled;
            vitaminB6Textbox.Enabled = isEnabled;
            vitaminB12Textbox.Enabled = isEnabled;
            vitaminCTextbox.Enabled = isEnabled;
            vitaminDTextbox.Enabled = isEnabled;
            vitaminETextbox.Enabled = isEnabled;
            folicAcidTextbox.Enabled = isEnabled;
            calciumTextbox.Enabled = isEnabled;
            ironTextbox.Enabled = isEnabled;
            sodiumTextbox.Enabled = isEnabled;
            potassiumTextbox.Enabled = isEnabled;
            phosphorusTextbox.Enabled = isEnabled;
            magnesiumTextbox.Enabled = isEnabled;
            zincTextbox.Enabled = isEnabled;
            seleniumTextbox.Enabled = isEnabled;
        }

        private void FoodProductView_FormClosing(object sender, FormClosingEventArgs e)
        {
            bool wasDialogCompleted = PromptUserToSaveChanges();

            if (!wasDialogCompleted)
                e.Cancel = true;
        }


        // Returns true if the user selected anything but cancel, false if the user cancelled the dialog.
        private bool PromptUserToSaveChanges()
        {
            bool wasSaveDialogCompleted = true;

            if (hasMadeChange)
            {
                DialogResult result = MessageBox.Show("Vill du spara ändringarna?", "Spara", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                if (result == DialogResult.Cancel)
                    wasSaveDialogCompleted = false;
                else if (result == DialogResult.Yes)
                    SaveFoodProduct();
            }

            return wasSaveDialogCompleted;
        }
    }
}